package com.xcity.game.activity.surprise7days;

import java.util.Collection;
import java.util.List;

import com.xcity.db.entity.Player;
import com.xcity.game.activity.ActivityService;
import com.xcity.game.activity2.ActivityIds;
import com.xcity.game.common.Cause;
import com.xcity.game.common.MessageConst;
import com.xcity.game.common.PlayerPool;
import com.xcity.game.event.GameEvents;
import com.xcity.game.mail.MailAttach;
import com.xcity.game.mail.MailService;
import com.xcity.game.player.PlayerService;
import com.xcity.pomelo.PomeloRoute;
import com.xcity.pomelo.push.msg.ActivityStatePush;
import com.xcity.pomelo.push.msg.TipPush;
import com.xcity.pomelo.request.ActivitySurprise7DaysInfoRequest;
import com.xcity.pomelo.request.ActivitySurprise7DaysRockRequest;
import com.xcity.pomelo.response.ActivitySurprise7DaysInfoResponse;
import com.xcity.pomelo.response.ActivitySurprise7DaysRockResponse;
import com.xcity.pomelo.response.HintResponse;

import naga.x.App;
import naga.x.event.Event;
import naga.x.event.EventListener;
import naga.x.game.template.TemplateService;
import naga.x.game.time.DayListener;
import naga.x.game.time.TimeUpdater;
import naga.x.net.Session;
import naga.x.net.annotation.OPHandler;
import naga.x.net.impl.pomelo.annotation.PomeloOP;
import naga.x.service.ServiceException;
import naga.x.util.TimeUtils;

@OPHandler
public class Surprise7DaysActivityService extends ActivityService implements EventListener, DayListener {
	
	private List<Surprise7DaysTemplate> templates;
	
	public static int FREE_TIMES = 3; // 每天3次免费摇取机会
	public static int COST_STONE = 5; // 花5钻石额外摇取
	public static int MAX_DAYS = 7;
	
	private static final byte S7DAYS_STATE_CAN_ROCK = 0; // 可摇取
	private static final byte S7DAYS_STATE_CAN_GET_REWARD = 1; // 可领奖
	private static final byte S7DAYS_STATE_REWARDED = 2; // 已领奖

	@Override
	public void startup() throws ServiceException {
		templates = App.getApp().getServiceManager().get(TemplateService.class).getTemplatesList(Surprise7DaysTemplate.class);
		App.getApp().getEventManager().register(this);
		TimeUpdater.getInstance().addDayListener(this);
	}

	@Override
	public void shutdown() throws ServiceException {
	}
	
	@Override
	public int[] getEventTypes() {
		return new int[] { GameEvents.EVENT_PLAYER_LOADED };
	}
	
	@Override
	public void handleEvent(Event event) {
		playerLoaded(event.getParameter());
	}
	
	@Override
	public boolean dayChanged() {
		Collection<Player> players = App.getApp().getServiceManager().get(PlayerService.class).getOnlinePlayers();
		for (Player player : players) {
			tryReward(player);
		}
		return true;
	}

	private void playerLoaded(Player player) {
		if (tryReward(player) == S7DAYS_STATE_CAN_ROCK) {
			player.send(new ActivityStatePush(ActivityIds.ACTIVITY_SURPRISE_7DAYS, STATE_OPENED));
		}
	}
	
	private byte tryReward(Player player) {
		int firstRockDay = getFirstRockDay(player);
		if (firstRockDay == -1) {
			return S7DAYS_STATE_REWARDED;
		}
		int todayIndex = TimeUtils.getDayGap(firstRockDay, TimeUpdater.getInstance().today());
		//TimeUpdater.getInstance().today() - firstRockDay;
		if (todayIndex >= MAX_DAYS) {
			player.poolSet(PlayerPool.PROPERTY_ACTIVITY_SURPRISE_7DAYS_FIRST_ROCK_DAY, -1); // 标记已领取
			int gold = getRewardGold(player);
			MailAttach attach = new MailAttach(gold, 0);
			App.getApp().getServiceManager().get(MailService.class).sendSystemMail(
					player.getId(),
					MessageConst.ACTIVITY_SURPRISE_7DAYS_MAIL_TITLE,
					MessageConst.ACTIVITY_SURPRISE_7DAYS_MAIL_CONTENT,
					attach);
			LOG.info("[ACTIVITY SURPRISE7DAYS REWARD]ID[{}]GOLD[{}]CAUSE[{}]", player.getId(), gold, Cause.ACTIVITY_SURPRISE_7DAYS);
			return S7DAYS_STATE_REWARDED;
		}
		return S7DAYS_STATE_CAN_ROCK;
	}
	
	private static int getLeftFreeTimes(Player player) {
		int lastRockDay = player.getPool().getIntValue(PlayerPool.PROPERTY_ACTIVITY_SURPRISE_7DAYS_LAST_ROCK_DAY);
		if (lastRockDay != TimeUpdater.getInstance().today()) {
			return FREE_TIMES;
		}
		int n = FREE_TIMES - player.getPool().getIntValue(PlayerPool.PROPERTY_ACTIVITY_SURPRISE_7DAYS_ROCKED_TIMES);
		return n > 0 ? n : 0;
	}
	
	private static void addRockTimes(Player player, int n) {
		int lastRockDay = player.getPool().getIntValue(PlayerPool.PROPERTY_ACTIVITY_SURPRISE_7DAYS_LAST_ROCK_DAY);
		int times = player.getPool().getIntValue(PlayerPool.PROPERTY_ACTIVITY_SURPRISE_7DAYS_ROCKED_TIMES);
		if (lastRockDay != TimeUpdater.getInstance().today()) {
			player.poolSet(PlayerPool.PROPERTY_ACTIVITY_SURPRISE_7DAYS_LAST_ROCK_DAY, TimeUpdater.getInstance().today());
			times = 0;
		}
		player.poolSet(PlayerPool.PROPERTY_ACTIVITY_SURPRISE_7DAYS_ROCKED_TIMES, times + n);
	}
	
	private static short[] getRockedNums(Player player) {
		short[] arr = player.getPool().getObject(PlayerPool.PROPERTY_ACTIVITY_SURPRISE_7DAYS, short[].class);
		if (arr == null) {
			arr = new short[] { -1, -1, -1, -1, -1, -1, -1 };
			player.poolSet(PlayerPool.PROPERTY_ACTIVITY_SURPRISE_7DAYS, arr);
		}
		return arr;
	}
	
	private static int getFirstRockDay(Player player) {
		int firstRockDay = player.getPool().getIntValue(PlayerPool.PROPERTY_ACTIVITY_SURPRISE_7DAYS_FIRST_ROCK_DAY);
		if (firstRockDay == 0) {
			firstRockDay = TimeUpdater.getInstance().today();
			player.poolSet(PlayerPool.PROPERTY_ACTIVITY_SURPRISE_7DAYS_FIRST_ROCK_DAY, firstRockDay);
		}
		return firstRockDay;
	}
	
	private void tryAutoRock(short[] nums, int todayIndex) {
		if (todayIndex > MAX_DAYS) {
			todayIndex = MAX_DAYS;
		}
		for (int i = 0; i < todayIndex; i++) {
			if (nums[i] == -1) {
				// 系统随机
				nums[i] = (short) templates.get(i).makeRandomNumberAutomatically();
			}
		}
	}
	
	@PomeloOP(PomeloRoute.ACTIVITY_SURPRISE_7DAYS_INFO)
	protected void requestInfo(Session session, ActivitySurprise7DaysInfoRequest req) {
		Player player = session.getClient();
		int firstRockDay = getFirstRockDay(player);
		if (firstRockDay == -1) { // 已领奖
			session.send(new HintResponse(req.getSerial(), MessageConst.REWARD_ALREADY_RECEIVED));
			return;
		}
		int todayIndex = TimeUtils.getDayGap(firstRockDay, TimeUpdater.getInstance().today());
		//TimeUpdater.getInstance().today() - firstRockDay;
		short[] nums = getRockedNums(player);
		tryAutoRock(nums, todayIndex);
		byte state = todayIndex >= MAX_DAYS ? S7DAYS_STATE_CAN_GET_REWARD : S7DAYS_STATE_CAN_ROCK;
		session.send(new ActivitySurprise7DaysInfoResponse(req.getSerial(), state, todayIndex + 1, nums, getLeftFreeTimes(player), COST_STONE));
	}
	
	@PomeloOP(PomeloRoute.ACTIVITY_SURPRISE_7DAYS_ROCK)
	protected void requestRock(Session session, ActivitySurprise7DaysRockRequest req) {
		Player player = session.getClient();
		int firstRockDay = getFirstRockDay(player);
		if (firstRockDay == -1) { // 已领奖
			session.send(new HintResponse(req.getSerial(), MessageConst.REWARD_ALREADY_RECEIVED));
			return;
		}
		int todayIndex = TimeUtils.getDayGap(firstRockDay, TimeUpdater.getInstance().today());
		//TimeUpdater.getInstance().today() - firstRockDay;
		short[] nums = getRockedNums(player);
		tryAutoRock(nums, todayIndex);
		if (todayIndex >= MAX_DAYS) { // 已超过7天
			session.send(new HintResponse(req.getSerial(), MessageConst.REWARD_CAN_RECEIVE));
			return;
		}
		short n = nums[todayIndex];
		if (n == 9) { // 已摇到最大数字
			session.send(new TipPush(MessageConst.ACTIVITY_SURPRISE_7DAYS_NUM_MAX));
		} else {
			if (getLeftFreeTimes(player) <= 0 && !player.costStone(COST_STONE, Cause.ACTIVITY_SURPRISE_7DAYS)) {
				session.send(new HintResponse(req.getSerial(), MessageConst.STONE_NOT_ENOUTH));
				return;
			}
			addRockTimes(player, 1);
			n = (short) templates.get(todayIndex).makeRandomNumberManually();
			nums[todayIndex] = n;
		}
		byte state = todayIndex >= MAX_DAYS ? S7DAYS_STATE_CAN_GET_REWARD : S7DAYS_STATE_CAN_ROCK;
		int leftFreeTimes = getLeftFreeTimes(player);
		session.send(new ActivitySurprise7DaysRockResponse(req.getSerial(), state, todayIndex + 1, n, leftFreeTimes, COST_STONE));
		LOG.info("[ACTIVITY SURPRISE7DAYS]ID[{}]DAYS[{}]NUM[{}]FREE[{}]", player.getId(), todayIndex, n, leftFreeTimes);
	}

//	@PomeloOP(PomeloRoute.ACTIVITY_SURPRISE_7DAYS_GET_REWARD)
//	protected void requestReward(Session session, ActivitySurprise7DaysRewardRequest req) {
//		Player player = session.getClient();
//		int firstRockDay = getFirstRockDay(player);
//		if (firstRockDay == -1) { // 已领奖
//			session.send(new HintResponse(req.getSerial(), MessageConst.REWARD_ALREADY_RECEIVED));
//			return;
//		}
//		short[] nums = getRockedNums(player);
//		if (nums[nums.length - 1] == -1) { // 最高位（百万位）未摇取
//			session.send(new HintResponse(req.getSerial(), MessageConst.CAN_NOT_GET_REWARD));
//			return;
//		}
//		player.poolSet(PlayerPool.PROPERTY_ACTIVITY_SURPRISE_7DAYS_FIRST_ROCK_DAY, -1); // 标记已领取
//		int gold = getRewardGold(player);
//		player.addGold(gold, Cause.ACTIVITY_SURPRISE_7DAYS);
//		session.send(new ActivitySurprise7DaysRewardResponse(req.getSerial(), S7DAYS_STATE_REWARDED, gold));
//		LOG.info("[ACTIVITY SURPRISE7DAYS REWARD]ID[{}]GOLD[{}]", player.getId(), gold);
//	}
	
	/**
	 * 计算可领取的现金
	 * @param player
	 * @return
	 */
	private int getRewardGold(Player player) {
		short[] nums = getRockedNums(player);
		int gold = 0;
		int mul = 1;
		for (int i = 0; i < nums.length; i++) {
			if (nums[i] == -1) {
				// 系统随机
				nums[i] = (short) templates.get(i).makeRandomNumberAutomatically();
			}
			gold += nums[i] * mul;
			mul *= 10;
		}
		return gold;
	}


}
